"use strict";

const path = require("path");
const pkgDir = require("pkg-dir").sync;
const npminstall = require("npminstall");
const pathExists = require("path-exists").sync;
const { isObject } = require("@azir-cli/utils");
const formatPath = require("@azir-cli/format-path");
const log = require("@azir-cli/log");
const { getNpmInfo, getDefaultRegistry } = require("@azir-cli/get-npm-info");
const fse = require("fs-extra");
class Package {
  constructor(options = {}) {
    if (!isObject(options)) {
      throw new Error("Package类的options必须是一个对象！");
    }
    // package的目标路径
    this.targetPath = options.targetPath;
    // 缓存路径
    this.storeDir = options.storeDir;
    // package的name
    this.packageName = options.packageName;
    // package版本
    this.packageVersion = options.packageVersion;
    this.catchFilePathPrefix = this.packageName.replace("/", "_");
  }

  get cacheFilePath() {
    return path.resolve(
      this.storeDir,
      `_${this.catchFilePathPrefix}@${this.packageVersion}@${this.packageName}`
    );
  }
  getCacheFilePathWithVersion(version) {
    return path.resolve(
      this.storeDir,
      `_${this.catchFilePathPrefix}@${version}@${this.packageName}`
    );
  }

  async prepare() {
    if (this.prepared) return;
    if (this.storeDir && !pathExists(this.storeDir)) {
      fse.mkdirpSync(this.storeDir);
    }
    if (this.packageVersion === "latest") {
      this.packageVersion = this.lastVersion = (
        await getNpmInfo(this.packageName)
      ).lastVersion;
    }
    this.prepared = true;
  }

  /**
   * 判断当前Package是否存在
   */
  async exists() {
    if (this.storeDir) {
      await this.prepare();
      return pathExists(this.cacheFilePath);
    } else {
      return pathExists(this.targetPath);
    }
  }

  /**
   * 安装Package
   */
  async install(registry) {
    await this.prepare();
    log.debug(this.packageName, this.packageVersion);
    return await npminstall({
      root: this.targetPath,
      storeDir: this.storeDir,
      registry: registry || getDefaultRegistry(),
      pkgs: [{ name: this.packageName, version: this.packageVersion }],
    });
  }

  /**
   * 更新Package
   */
  async update() {
    await this.prepare();
    const lastVersion = this.lastVersion;
    if (lastVersion) {
      const lastVersionPkgPath = this.getCacheFilePathWithVersion(lastVersion);
      if (!pathExists(lastVersionPkgPath)) {
        await npminstall({
          root: this.targetPath,
          storeDir: this.storeDir,
          registry: getDefaultRegistry(),
          pkgs: [{ name: this.packageName, version: lastVersion }],
        });
        this.packageVersion = lastVersion;
      }
      return lastVersionPkgPath;
    } else {
      throw new Error("can not get lastVersion");
    }
  }

  /**
   * 获取入口文件路径
   */
  getRootFilePath() {
    function _getRootPath(targetPath) {
      //1. 获取package.json所在目录
      const packageJsonDir = pkgDir(targetPath);
      if (packageJsonDir) {
        //2. 获取package.json
        const pkgJson = require(path.resolve(packageJsonDir, "package.json"));
        //3. 获取入口，main/lib
        if (pkgJson && pkgJson.main) {
          //4. 路径兼容
          return formatPath(path.resolve(packageJsonDir, pkgJson.main));
        }
        log.error("找不到 package.json 或者 入口文件 main！");
      }
      return null;
    }
    if (this.storeDir) {
      return _getRootPath(this.storeDir);
    } else {
      return _getRootPath(this.targetPath);
    }
  }
}

module.exports = Package;
